<template>
  <div v-if="showPagination" class="base-pagination">
    <!-- 简单分页模式 -->
    <template v-if="mode === 'simple'">
      <div class="base-pagination__simple">
        <van-button
          :disabled="currentPage <= 1"
          size="small"
          @click="handlePrevPage"
        >
          上一页
        </van-button>
        <span class="base-pagination__info">
          {{ currentPage }} / {{ totalPages }}
        </span>
        <van-button
          :disabled="currentPage >= totalPages"
          size="small"
          @click="handleNextPage"
        >
          下一页
        </van-button>
      </div>
    </template>

    <!-- 完整分页模式 -->
    <template v-else-if="mode === 'full'">
      <div class="base-pagination__full">
        <!-- 总数信息 -->
        <div v-if="showTotal" class="base-pagination__total">
          共 {{ total }} 条数据
        </div>

        <!-- 分页器 -->
        <div class="base-pagination__pager">
          <!-- 上一页 -->
          <van-button
            :disabled="currentPage <= 1"
            size="small"
            icon="arrow-left"
            @click="handlePrevPage"
          />

          <!-- 页码 -->
          <div class="base-pagination__pages">
            <template v-for="page in pageList" :key="page">
              <van-button
                v-if="page === '...'"
                size="small"
                disabled
                class="base-pagination__ellipsis"
              >
                ...
              </van-button>
              <van-button
                v-else
                :type="page === currentPage ? 'primary' : 'default'"
                size="small"
                @click="handlePageChange(page)"
              >
                {{ page }}
              </van-button>
            </template>
          </div>

          <!-- 下一页 -->
          <van-button
            :disabled="currentPage >= totalPages"
            size="small"
            icon="arrow-right"
            @click="handleNextPage"
          />
        </div>

        <!-- 页面大小选择 -->
        <div v-if="showSizeChanger" class="base-pagination__size">
          <van-field
            v-model="currentPageSize"
            type="number"
            label="每页"
            suffix="条"
            :min="1"
            :max="maxPageSize"
            @change="handlePageSizeChange"
          />
        </div>

        <!-- 快速跳转 -->
        <div v-if="showQuickJumper" class="base-pagination__jumper">
          <span>跳至</span>
          <van-field
            v-model="jumpPage"
            type="number"
            :min="1"
            :max="totalPages"
            @keyup.enter="handleJump"
          />
          <span>页</span>
          <van-button size="small" @click="handleJump">
            确定
          </van-button>
        </div>
      </div>
    </template>

    <!-- 加载更多模式 */
    <template v-else-if="mode === 'loadmore'">
      <div class="base-pagination__loadmore">
        <van-button
          v-if="hasMore"
          :loading="loading"
          block
          @click="handleLoadMore"
        >
          {{ loading ? '加载中...' : '加载更多' }}
        </van-button>
        <div v-else class="base-pagination__finished">
          {{ finishedText }}
        </div>
      </div>
    </template>

    <!-- 无限滚动模式 -->
    <template v-else-if="mode === 'infinite'">
      <van-list
        v-model:loading="loading"
        :finished="!hasMore"
        :finished-text="finishedText"
        :error="error"
        error-text="请求失败，点击重新加载"
        @load="handleInfiniteLoad"
      >
        <slot />
      </van-list>
    </template>
  </div>
</template>

<script>
import { ref, computed, watch, defineComponent } from 'vue'

export default defineComponent({
  name: 'BasePagination',
  props: {
    /**
     * 当前页码
     */
    modelValue: {
      type: Number,
      default: 1
    },
    /**
     * 总数据量
     */
    total: {
      type: Number,
      default: 0
    },
    /**
     * 每页显示条数
     */
    pageSize: {
      type: Number,
      default: 10
    },
    /**
     * 分页模式
     */
    mode: {
      type: String,
      default: 'simple',
      validator: (value) => ['simple', 'full', 'loadmore', 'infinite'].includes(value)
    },
    /**
     * 是否显示总数
     */
    showTotal: {
      type: Boolean,
      default: true
    },
    /**
     * 是否显示页面大小选择器
     */
    showSizeChanger: {
      type: Boolean,
      default: false
    },
    /**
     * 是否显示快速跳转
     */
    showQuickJumper: {
      type: Boolean,
      default: false
    },
    /**
     * 页面大小选项
     */
    pageSizeOptions: {
      type: Array,
      default: () => [10, 20, 50, 100]
    },
    /**
     * 最大页面大小
     */
    maxPageSize: {
      type: Number,
      default: 1000
    },
    /**
     * 显示的页码按钮数量
     */
    showPageCount: {
      type: Number,
      default: 5
    },
    /**
     * 是否正在加载
     */
    loading: {
      type: Boolean,
      default: false
    },
    /**
     * 是否有更多数据
     */
    hasMore: {
      type: Boolean,
      default: true
    },
    /**
     * 加载完成文本
     */
    finishedText: {
      type: String,
      default: '没有更多了'
    },
    /**
     * 是否加载错误
     */
    error: {
      type: Boolean,
      default: false
    },
    /**
     * 是否隐藏单页
     */
    hideOnSinglePage: {
      type: Boolean,
      default: false
    }
  },
  emits: ['update:modelValue', 'change', 'page-size-change', 'load-more'],
  setup(props, { emit }) {
    const currentPageSize = ref(props.pageSize)
    const jumpPage = ref('')

    /**
     * 当前页码
     */
    const currentPage = computed({
      get: () => props.modelValue,
      set: (value) => emit('update:modelValue', value)
    })

    /**
     * 总页数
     */
    const totalPages = computed(() => {
      return Math.ceil(props.total / currentPageSize.value) || 1
    })

    /**
     * 是否显示分页
     */
    const showPagination = computed(() => {
      if (props.hideOnSinglePage && totalPages.value <= 1) {
        return false
      }
      return props.total > 0 || props.mode === 'infinite'
    })

    /**
     * 页码列表
     */
    const pageList = computed(() => {
      const pages = []
      const total = totalPages.value
      const current = currentPage.value
      const showCount = props.showPageCount

      if (total <= showCount) {
        // 总页数小于等于显示页数，显示所有页码
        for (let i = 1; i <= total; i++) {
          pages.push(i)
        }
      } else {
        // 总页数大于显示页数，需要省略
        const half = Math.floor(showCount / 2)
        let start = current - half
        let end = current + half

        if (start < 1) {
          start = 1
          end = showCount
        }

        if (end > total) {
          end = total
          start = total - showCount + 1
        }

        // 添加首页
        if (start > 1) {
          pages.push(1)
          if (start > 2) {
            pages.push('...')
          }
        }

        // 添加中间页码
        for (let i = start; i <= end; i++) {
          pages.push(i)
        }

        // 添加尾页
        if (end < total) {
          if (end < total - 1) {
            pages.push('...')
          }
          pages.push(total)
        }
      }

      return pages
    })

    /**
     * 页码变化处理
     */
    const handlePageChange = (page) => {
      if (page !== currentPage.value && page >= 1 && page <= totalPages.value) {
        currentPage.value = page
        emit('change', page, currentPageSize.value)
      }
    }

    /**
     * 上一页
     */
    const handlePrevPage = () => {
      handlePageChange(currentPage.value - 1)
    }

    /**
     * 下一页
     */
    const handleNextPage = () => {
      handlePageChange(currentPage.value + 1)
    }

    /**
     * 页面大小变化处理
     */
    const handlePageSizeChange = (size) => {
      const newSize = parseInt(size)
      if (newSize !== currentPageSize.value && newSize > 0) {
        currentPageSize.value = newSize
        // 重新计算当前页码
        const newPage = Math.min(currentPage.value, Math.ceil(props.total / newSize))
        currentPage.value = newPage
        emit('page-size-change', newSize, newPage)
        emit('change', newPage, newSize)
      }
    }

    /**
     * 快速跳转处理
     */
    const handleJump = () => {
      const page = parseInt(jumpPage.value)
      if (page && page >= 1 && page <= totalPages.value) {
        handlePageChange(page)
        jumpPage.value = ''
      }
    }

    /**
     * 加载更多处理
     */
    const handleLoadMore = () => {
      emit('load-more')
    }

    /**
     * 无限滚动加载处理
     */
    const handleInfiniteLoad = () => {
      emit('load-more')
    }

    // 监听页面大小变化
    watch(() => props.pageSize, (newSize) => {
      currentPageSize.value = newSize
    })

    return {
      currentPage,
      currentPageSize,
      jumpPage,
      totalPages,
      showPagination,
      pageList,
      handlePageChange,
      handlePrevPage,
      handleNextPage,
      handlePageSizeChange,
      handleJump,
      handleLoadMore,
      handleInfiniteLoad
    }
  }
})
</script>

<style lang="scss" scoped>
.base-pagination {
  padding: 16px;
  background-color: #fff;

  &__simple {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
  }

  &__info {
    font-size: 14px;
    color: #646566;
  }

  &__full {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  &__total {
    font-size: 14px;
    color: #646566;
    text-align: center;
  }

  &__pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
  }

  &__pages {
    display: flex;
    align-items: center;
    gap: 4px;
  }

  &__ellipsis {
    cursor: default;
  }

  &__size {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;

    .van-field {
      width: 80px;
    }
  }

  &__jumper {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font-size: 14px;
    color: #646566;

    .van-field {
      width: 60px;
    }
  }

  &__loadmore {
    padding: 16px 0;
  }

  &__finished {
    padding: 16px 0;
    font-size: 14px;
    color: #969799;
    text-align: center;
  }
}

// 响应式设计
@media (max-width: 768px) {
  .base-pagination {
    &__full {
      gap: 8px;
    }

    &__pager {
      flex-wrap: wrap;
      gap: 4px;
    }

    &__size,
    &__jumper {
      flex-wrap: wrap;
      gap: 4px;
    }
  }
}
</style>